/*
 * This file (AkColorMngrStdrd.java) is protected by the GNU GPL licence (v2). 
 * Please read the license.txt attached for further informations. 
 * 
 */

package alkwarel.gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import artx.utils.AxLog;

/**
 * Standard color chooser dialog.
 * 
 * @author Xavier Gouchet
 * 
 */
public class AkColorDlg extends JDialog implements ChangeListener,
		ActionListener {

	private static final long serialVersionUID = 1L;

	private JTabbedPane mainPanel = null;

	private Color selectedColor = null;

	private int exitStatus = -1;

	private JPanel rgbPanel = null;

	private JPanel hsvPanel = null;

	private JPanel rgbColorPreview = null;

	private JPanel hsvColorPreview = null;

	private JSlider redSlider = null;

	private JSlider greenSlider = null;

	private JSlider blueSlider = null;

	private JSlider alphaSlider1 = null;

	private JSlider hueSlider = null;

	private JSlider satSlider = null;

	private JSlider valSlider = null;

	private JSlider alphaSlider2 = null;

	private int redVal = 0;

	private int greenVal = 0;

	private int blueVal = 0;

	private int hueVal = 0;

	private int satVal = 0;

	private int valVal = 0;

	private int alphaVal = 0;

	/**
	 * Standard constructor.
	 * 
	 * @param owner
	 *            the master window calling this dialog
	 */
	public AkColorDlg(Frame owner) {
		super(owner);
		this.setResizable(false);
		this.setTitle("Color Chooser");
		this.setContentPane(this.getMainPanel());
		this.selectedColor = new Color(0, 0, 0);
		this.pack();

		URL imageURL = AkColorDlg.class
				.getResource("/artx/gui/rsc/applications-graphics.png");
		ImageIcon icn = null;
		if (imageURL != null) {
			this.setIconImage(new ImageIcon(imageURL).getImage());
		}

	}

	private JTabbedPane getMainPanel() {
		if (this.mainPanel == null) {
			this.mainPanel = new JTabbedPane();
			this.mainPanel.addTab("RGB", null, getRGBPanel(), null);
			this.mainPanel.addTab("HSV", null, getHSVPanel(), null);
		}
		return this.mainPanel;
	}

	private Component getHSVPanel() {
		if (this.hsvPanel == null) {
			this.hsvPanel = new JPanel();
			this.hsvPanel.setLayout(new GridBagLayout());
			GridBagConstraints gbc = new GridBagConstraints();
			gbc.gridx = 0;
			gbc.gridwidth = 3;
			gbc.insets = new Insets(5, 5, 5, 5);

			gbc.gridy = 0;
			this.hueSlider = new JSlider(JSlider.HORIZONTAL, 0, 255,
					this.hueVal);
			this.hueSlider.setToolTipText("Hue");
			this.hueSlider.addChangeListener(this);
			this.hsvPanel.add(this.hueSlider, gbc);

			gbc.gridy = 1;
			this.satSlider = new JSlider(JSlider.HORIZONTAL, 0, 255,
					this.satVal);
			this.satSlider.setToolTipText("Saturation");
			this.satSlider.addChangeListener(this);
			this.hsvPanel.add(this.satSlider, gbc);

			gbc.gridy = 2;
			this.valSlider = new JSlider(JSlider.HORIZONTAL, 0, 255,
					this.valVal);
			this.valSlider.setToolTipText("Value");
			this.valSlider.addChangeListener(this);
			this.hsvPanel.add(this.valSlider, gbc);

			gbc.gridy = 3;
			this.alphaSlider2 = new JSlider(JSlider.HORIZONTAL, 0, 255,
					this.alphaVal);
			this.alphaSlider2.setToolTipText("Alpha");
			this.alphaSlider2.addChangeListener(this);
			this.hsvPanel.add(this.alphaSlider2, gbc);

			gbc.gridx = 0;
			gbc.gridy = 4;
			gbc.gridwidth = 1;
			gbc.fill = GridBagConstraints.BOTH;
			this.hsvPanel.add(this.getHSVColorPreview(), gbc);
			gbc.gridx = 1;
			JButton okBtn = new JButton("Ok");
			okBtn.setPreferredSize(new Dimension(75, 30));
			okBtn.addActionListener(this);
			this.hsvPanel.add(okBtn, gbc);
			gbc.gridx = 2;
			JButton cancelBtn = new JButton("Cancel");
			cancelBtn.setPreferredSize(new Dimension(75, 30));
			cancelBtn.addActionListener(this);
			this.hsvPanel.add(cancelBtn, gbc);
		}
		return this.hsvPanel;
	}

	private Component getRGBPanel() {
		if (this.rgbPanel == null) {
			this.rgbPanel = new JPanel();
			this.rgbPanel.setLayout(new GridBagLayout());
			GridBagConstraints gbc = new GridBagConstraints();
			gbc.gridx = 0;
			gbc.gridwidth = 3;
			gbc.insets = new Insets(5, 5, 5, 5);

			gbc.gridy = 0;
			this.redSlider = new JSlider(JSlider.HORIZONTAL, 0, 255,
					this.redVal);
			this.redSlider.setToolTipText("Red");
			this.redSlider.addChangeListener(this);
			this.rgbPanel.add(this.redSlider, gbc);

			gbc.gridy = 1;
			this.greenSlider = new JSlider(JSlider.HORIZONTAL, 0, 255,
					this.greenVal);
			this.greenSlider.setToolTipText("Green");
			this.greenSlider.addChangeListener(this);
			this.rgbPanel.add(this.greenSlider, gbc);

			gbc.gridy = 2;
			this.blueSlider = new JSlider(JSlider.HORIZONTAL, 0, 255,
					this.blueVal);
			this.blueSlider.setToolTipText("Blue");
			this.blueSlider.addChangeListener(this);
			this.rgbPanel.add(this.blueSlider, gbc);

			gbc.gridy = 3;
			this.alphaSlider1 = new JSlider(JSlider.HORIZONTAL, 0, 255,
					this.alphaVal);
			this.alphaSlider1.setToolTipText("Alpha");
			this.alphaSlider1.addChangeListener(this);
			this.rgbPanel.add(this.alphaSlider1, gbc);

			gbc.gridx = 0;
			gbc.gridy = 4;
			gbc.gridwidth = 1;
			gbc.fill = GridBagConstraints.BOTH;
			this.rgbPanel.add(this.getRGBColorPreview(), gbc);
			gbc.gridx = 1;
			JButton okBtn = new JButton("Ok");
			okBtn.setPreferredSize(new Dimension(75, 30));
			okBtn.addActionListener(this);
			this.rgbPanel.add(okBtn, gbc);
			gbc.gridx = 2;
			JButton cancelBtn = new JButton("Cancel");
			cancelBtn.setPreferredSize(new Dimension(75, 30));
			cancelBtn.addActionListener(this);
			this.rgbPanel.add(cancelBtn, gbc);
		}
		return this.rgbPanel;
	}

	private Component getRGBColorPreview() {
		if (this.rgbColorPreview == null) {
			this.rgbColorPreview = new JPanel();
			this.rgbColorPreview.setPreferredSize(new Dimension(40, 30));
			this.rgbColorPreview.setBackground(new Color(0, 0, 0));
		}
		return this.rgbColorPreview;
	}

	private Component getHSVColorPreview() {
		if (this.hsvColorPreview == null) {
			this.hsvColorPreview = new JPanel();
			this.hsvColorPreview.setPreferredSize(new Dimension(40, 30));
			this.hsvColorPreview.setBackground(new Color(0, 0, 0));
		}
		return this.hsvColorPreview;
	}

	/**
	 * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
	 */
	public void stateChanged(ChangeEvent e) {
		if (this.mainPanel.getSelectedIndex() == 0) {
			if ((e.getSource() == this.redSlider)
					|| (e.getSource() == this.greenSlider)
					|| (e.getSource() == this.blueSlider)
					|| (e.getSource() == this.alphaSlider1)) {
				this.redVal = this.redSlider.getValue();
				this.greenVal = this.greenSlider.getValue();
				this.blueVal = this.blueSlider.getValue();
				this.alphaVal = this.alphaSlider1.getValue();
				this.selectedColor = new Color(this.redVal, this.greenVal,
						this.blueVal);
				this.rgbColorPreview.setBackground(this.selectedColor);
				this.hsvColorPreview.setBackground(this.selectedColor);
				// TODO make a simple way to display alpha in the interface !
				float[] hsbvals = new float[3];
				Color.RGBtoHSB(this.redVal, this.greenVal, this.blueVal,
						hsbvals);
				this.hueSlider.setValue((int) (hsbvals[0] * 255));
				this.satSlider.setValue((int) (hsbvals[1] * 255));
				this.valSlider.setValue((int) (hsbvals[2] * 255));
				this.alphaSlider2.setValue(this.alphaVal);
			}
		}

		if (this.mainPanel.getSelectedIndex() == 1) {
			if ((e.getSource() == this.hueSlider)
					|| (e.getSource() == this.satSlider)
					|| (e.getSource() == this.valSlider)
					|| (e.getSource() == this.alphaSlider2)) {
				this.hueVal = this.hueSlider.getValue();
				this.satVal = this.satSlider.getValue();
				this.valVal = this.valSlider.getValue();
				this.alphaVal = this.alphaSlider2.getValue();
				this.selectedColor = new Color(Color.HSBtoRGB(
						this.hueVal / 255.0f, this.satVal / 255.0f,
						this.valVal / 255.0f));
				this.rgbColorPreview.setBackground(this.selectedColor);
				this.hsvColorPreview.setBackground(this.selectedColor);
				this.redSlider.setValue(this.selectedColor.getRed());
				this.greenSlider.setValue(this.selectedColor.getGreen());
				this.blueSlider.setValue(this.selectedColor.getBlue());
				this.alphaSlider1.setValue(this.alphaVal);
			}
		}
	}

	/**
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().toLowerCase().equals("ok")) {
			AxLog.Debug("AkColorDlg::actionPerformed =>> Validating colors");
			this.exitStatus = 0;
			this.Close();
		}
		if (e.getActionCommand().toLowerCase().equals("cancel")) {
			AxLog.Debug("AkColorDlg::actionPerformed =>> Canceling colors");
			this.exitStatus = -1;
			this.Close();
		}
	}

	private void Close() {
		this.setVisible(false);
	}

	/**
	 * 
	 * @return the exit status
	 */
	public int ExitStatus() {
		return this.exitStatus;
	}

	/**
	 * 
	 * @return the selected color
	 */
	public Color GetColor() {
		return new Color(this.selectedColor.getRed(), this.selectedColor
				.getGreen(), this.selectedColor.getBlue(), this.alphaVal);
	}

}
